﻿<!--
* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org>
* License: BSD
* This file is part of Open Source sipML5 solution <http://www.sipml5.org>
-->
<html>
<!-- head -->
<head>
    <title>Test SIP messages</title>
    <script src="src/tinySDP/src/tsdp_api.js" type="text/javascript"> </script>
</head>

<script type="text/javascript">

    var __s_browser = "firefox";

    var __msg1 = "v=0\r\n" +
	"o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n" +
	"s=\r\n" +
    "d=dummy header\r\n" +
	"i=A Seminar on the session description protocol\r\n" +
	"u=http://www.example.com/seminars/sdp.pdf\r\n" +
	"e=j.doe@example.com (Jane Doe)\r\n" +
	"p=+1 617 555-6011\r\n" +
	"c=IN IP4 host.atlanta.example.com\r\n" +
	"b=X-YZ:128\r\n" +
	"z=2882844526 -1h 2898848070 0\r\n" +
	"k=base64:ZWFzdXJlLg==\r\n" +
	"t=3034423619 3042462419\r\n" +
    "r=7d 1h 0 25h\r\n" +
	"r=604800 3600 0 90000\r\n" +
	"m=audio 49170 RTP/AVP 0 8 97 98\r\n" +
	"i=Audio line\r\n" +
	"c=IN IP4 otherhost.biloxi.example.com\r\n" +
	"k=base64:ZWFzdXJlLgdddddddddddddddddddddd==\r\n" +
	"a=rtpmap:0 PCMU/8000\r\n" +
	"a=rtpmap:8 PCMA/8000\r\n" +
	"a=rtpmap:97 iLBC/8000\r\n" +
	"a=rtpmap:98 AMR-WB/16000\r\n" +
    "a=fmtp:98 octet-align=1\r\n" +
    "w=my dummy header\r\n" +
	"m=video 51372 RTP/AVP 31 32\r\n" +
	"i=Video line\r\n" +
	"b=A-YZ:92\r\n" +
	"b=B-YZ:256\r\n" +
	"a=rtpmap:31 H261/90000\r\n" +
	"a=rtpmap:32 MPV/90000\r\n" +
    "a=ssrc:3678808980 label:PÃ©riphÃ©rique vidÃ©o US\r\n" +
	"a=recvonly\r\n";

    var __msg2 = "v=0\r\n" +
    "o=- 0 0 IN IP4 127.0.0.1\r\n" +
    "s=-\r\n" +
    "t=0 0\r\n" +
    "e=Jane Doe <j.doe@example.com>\r\n" +
    "u=sip:alice@doubango.org\r\n" +
    "p=+1 617 555-6011\r\n" +
    "s=testing sdp parser\r\n" +
    "i=session-level information\r\n" +
    "m=audio 1660 RTP/AVP 103 104 0 8 106 105 13 126\r\n" +
    "i=media-level information\r\n" +
    "k=audio_key\r\n" +
    "c=IN IP4 192.168.0.12\r\n" +
    "a=rtcp:1659 IN IP4 192.168.0.12\r\n" +
    "a=candidate:1 2 udp 1 192.168.0.12 1659 typ host name rtcp network_name {9EBBE687-CCE6-42D3-87F5-B57BB30DEE23} username UsVLB4eUbeUoNqNX password bb2g1bdEtuzSPNYXvekos1 generation 0\r\n" +
    "a=candidate:1 1 udp 1 192.168.0.12 1660 typ host name rtp network_name {9EBBE687-CCE6-42D3-87F5-B57BB30DEE23} username EmcJDeNlp5eowR78 password gigGs6fimM/xmBHBuxv9tM generation 0\r\n" +
    "a=mid:audio\r\n" +
    "a=rtcp-mux\r\n" +
    "a=crypto:0 AES_CM_128_HMAC_SHA1_32 inline:HE2wXFpJetC6Crt2IYh2+DU9DgGRP9/GNF5k8duc \r\n" +
    "a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:Rb1sTMzeh4F1PwMBhsGAkE7IXU4bRsnPwYTe0V1C \r\n" +
    "a=rtpmap:103 ISAC/16000\r\n" +
    "a=rtpmap:104 ISAC/32000\r\n" +
    "a=rtpmap:0 PCMU/8000\r\n" +
    "a=rtpmap:8 PCMA/8000\r\n" +
    "a=rtpmap:106 CN/32000\r\n" +
    "a=rtpmap:105 CN/16000\r\n" +
    "a=rtpmap:13 CN/8000\r\n" +
    "a=rtpmap:126 telephone-event/8000\r\n" +
    "a=ssrc:516108910 cname:sET0y/IbFJhjVQNv\r\n" +
    "a=ssrc:516108910 mslabel:fd6ca735-ce47-4095-bcc8-659b86a16638\r\n" +
    "a=ssrc:516108910 label:Default\r\n" +
    "m=video 1662 RTP/AVP 100 101 102\r\n" +
    "i=media-level information\r\n" +
    "k=video_key\r\n" +
    "c=IN IP4 192.168.0.12\r\n" +
    "a=rtcp:1661 IN IP4 192.168.0.12\r\n" +
    "a=candidate:1 2 udp 1 192.168.0.12 1661 typ host name video_rtcp network_name {9EBBE687-CCE6-42D3-87F5-B57BB30DEE23} username +t7KNjDJQ2Hu7G/G password vEMwN5dTMPhWLDAvVmmGOo generation 0\r\n" +
    "a=candidate:1 1 udp 1 192.168.0.12 1662 typ host name video_rtp network_name {9EBBE687-CCE6-42D3-87F5-B57BB30DEE23} username HPOEJJ1JNO89vKqp password Q0S2fUEFYhRlFVrPH1b6zk generation 0\r\n" +
    "a=mid:video\r\n" +
    "a=rtcp-mux\r\n" +
    "a=crypto:0 AES_CM_128_HMAC_SHA1_80 inline:b1PujeHajYE0EqBykzHzMz7n+QGdXWv7nHdb9RBa \r\n" +
    "a=rtpmap:100 VP8/90000\r\n" +
    "a=rtpmap:101 red/90000\r\n" +
    "a=rtpmap:102 ulpfec/90000\r\n" +
    "a=ssrc:3678808980 cname:sET0y/IbFJhjVQNv\r\n" +
    "a=ssrc:3678808980 mslabel:fd6ca735-ce47-4095-bcc8-659b86a16638\r\n" +
    "a=ssrc:1197373411 label:Priphrique vido US\r\n";

    var __msg3 = "v=0\r\n" +
    "o=root 1506997520 1506997520 IN IP4 50.18.1.1\r\n" +
    "s=Asterisk PBX SVN-branch-11-r371571\r\n" +
    "c=IN IP4 50.18.1.1\r\n" +
    "t=0 0\r\n" +
    "m=audio 14150 RTP/SAVPF 8 0 101\r\n" +
    "a=rtpmap:8 PCMA/8000\r\n" +
    "a=rtpmap:0 PCMU/8000\r\n" +
    "a=rtpmap:101 telephone-event/8000\r\n" +
    "a=fmtp:101 0-16\r\n" +
    "a=silenceSupp:off - - - -\r\n" +
    "a=ptime:20\r\n" +
    "a=ice-ufrag:05a48c8d362c4daa6b7b53f84a57379c\r\n" +
    "a=ice-pwd:6715133d684e4e6936805c3371309d71\r\n" +
    "a=candidate:Haa89741 1 UDP 2130706431 10.165.1.1 14150 typ host\r\n" +
    "a=candidate:Haa89741 2 UDP 2130706430 10.165.1.1 14151 typ host\r\n" +
    "a=sendrecv\r\n" +
    "a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:BYgghgOrRI2kCAGtMZpuwUCwtqW4Cyp9VOP7HpD/\r\n" +
    "m=video 0 RTP/SAVPF 100 101 102\r\n";

    var __msg4 = "v=0\r\n" +
    "o=Mozilla-SIPUA 26256 0 IN IP4 0.0.0.0\r\n" +
    "s=SIP Call\r\n" +
    "t=0 0\r\n" +
    "a=ice-ufrag:889983ba\r\n" +
    "a=ice-pwd:c9aa4fda7abbca9d7f1ad01e239365e5\r\n" +
    "a=fingerprint:sha-256 D5:65:0F:49:CB:18:F2:FC:F0:83:77:80:96:4E:24:72:89:38:EE:C5:D2:14:3F:69:57:8B:4C:49:5B:EB:34:7C\r\n" +
    "m=audio 51709 RTP/SAVPF 109 0 8 101\r\n" +
    "c=IN IP4 88.179.39.5\r\n" +
    "a=rtpmap:109 opus/48000/2\r\n" +
    "a=ptime:20\r\n" +
    "a=rtpmap:0 PCMU/8000\r\n" +
    "a=rtpmap:8 PCMA/8000\r\n" +
    "a=rtpmap:101 telephone-event/8000\r\n" +
    "a=fmtp:101 0-15\r\n" +
    "a=sendrecv\r\n" +
    "a=candidate:0 1 UDP 2111832319 192.168.0.11 51709 typ host\r\n" +
    "a=candidate:1 1 UDP 1692467199 88.179.39.5 51709 typ srflx raddr 192.168.0.11 rport 51709\r\n" +
    "a=candidate:0 2 UDP 2111832318 192.168.0.11 51710 typ host\r\n" +
    "a=candidate:1 2 UDP 1692467198 88.179.39.5 51710 typ srflx raddr 192.168.0.11 rport 51710\r\n" +
    "m=video 51711 RTP/SAVPF 120\r\n" +
    "c=IN IP4 88.179.39.5\r\n" +
    "a=rtpmap:120 VP8/90000\r\n" +
    "a=sendrecv\r\n" +
    "a=candidate:0 1 UDP 2111832319 192.168.0.11 51711 typ host\r\n" +
    "a=candidate:1 1 UDP 1692467199 88.179.39.5 51711 typ srflx raddr 192.168.0.11 rport 51711\r\n" +
    "a=candidate:0 2 UDP 2111832318 192.168.0.11 51712 typ host\r\n" +
    "a=candidate:1 2 UDP 1692467198 88.179.39.5 51712 typ srflx raddr 192.168.0.11 rport 51712\r\n" +
    "m=application 51713 SCTP/DTLS 5000 \r\n" +
    "c=IN IP4 88.179.39.5\r\n" +
    "a=fmtp:5000 protocol=webrtc-datachannel;streams=16\r\n" +
    "a=sendrecv\r\n" +
    "a=candidate:0 1 UDP 2111832319 192.168.0.11 51713 typ host\r\n" +
    "a=candidate:1 1 UDP 1692467199 88.179.39.5 51713 typ srflx raddr 192.168.0.11 rport 51713\r\n" +
    "a=candidate:0 2 UDP 2111832318 192.168.0.11 51714 typ host\r\n" +
    "a=candidate:1 2 UDP 1692467198 88.179.39.5 51714 typ srflx raddr 192.168.0.11 rport 51714\r\n";

    var __msg5 = "v=0\r\n" +
            "o=doubango 1983 678901 IN IP4 192.168.0.37\r\n" +
            "s=-\r\n" +
            "c=IN IP4 192.168.0.37\r\n" +
            "t=0 0\r\n" +
            "a=acap:1 setup:actpass\r\n" +
            "a=acap:2 fingerprint: SHA-1 99:2C:29:4B:FF:D1:FA:74:8C:C9:32:CD:66:A5:80:8C:12:18:D4:6C\r\n" +
            "a=acap:3 fingerprint: SHA-256 BE:8D:5B:BC:34:D8:73:70:EF:04:9B:7B:6F:69:60:5C:37:05:2A:6A:68:C0:E1:06:8C:35:47:83:80:8B:89:C6\r\n" +
            "a=tcap:1 UDP/TLS/RTP/SAVPF UDP/TLS/RTP/SAVP RTP/SAVPF RTP/SAVP RTP/AVPF\r\n" +
            "m=audio 6110 RTP/AVP 0 8 101\r\n" +
            "a=ptime:20\r\n" +
            "a=silenceSupp:off - - - -\r\n" +
            "a=rtpmap:0 PCMU/8000/1\r\n" +
            "a=rtpmap:8 PCMA/8000/1\r\n" +
            "a=rtpmap:101 telephone-event/8000/1\r\n" +
            "a=fmtp:101 0-16\r\n" +
            "a=acap:4 crypto:1 AES_CM_128_HMAC_SHA1_80 inline:UiNPpIsb+AsyjnBGs8kFho0COUV3NMENIGc0z3rg\r\n" +
            "a=acap:5 crypto:2 AES_CM_128_HMAC_SHA1_32 inline:1sx0U3hGC0Pa0pGhleb4cZTRQxa6Ot7+z3P7CciZ\r\n" +
            "a=pcfg:1 t=1 a=1,2|3\r\n" +
            "a=pcfg:2 t=2 a=1,2|3\r\n" +
            "a=pcfg:3 t=3 a=4,5\r\n" +
            "a=pcfg:4 t=4 a=4,5\r\n" +
            "a=sendrecv\r\n" +
            "a=rtcp-mux\r\n" +
            "a=ssrc:4121734221 cname:ldjWoB60jbyQlR6e\r\n" +
            "a=ssrc:4121734221 mslabel:6994f7d1-6ce9-4fbd-acfd-84e5131ca2e2\r\n" +
            "a=ssrc:4121734221 label:Doubango\r\n" +
            "m=video 33324 RTP/AVP 104 121 103 125 34\r\n" +
            "a=rtpmap:104 H264/90000\r\n" +
            "a=imageattr:104 recv [x=[128:16:640],y=[96:16:480]] send [x=[128:16:640],y=[96:16:480]]\r\n" +
            "a=fmtp:104 profile-level-id=42001e; packetization-mode=1\r\n" +
            "a=rtpmap:121 MP4V-ES/90000\r\n" +
            "a=imageattr:121 recv [x=[128:16:640],y=[96:16:480]] send [x=[128:16:640],y=[96:16:480]]\r\n" +
            "a=fmtp:121 profile-level-id=3\r\n" +
            "a=rtpmap:103 H263-1998/90000\r\n" +
            "a=fmtp:103 CIF=2;QCIF=2;SQCIF=2\r\n" +
            "a=rtpmap:125 theora/90000\r\n" +
            "a=imageattr:125 recv [x=[128:16:640],y=[96:16:480]] send [x=[128:16:640],y=[96:16:480]]\r\n" +
            "a=fmtp:125 sampling=YCbCr-4:2:0; width=640; height=480\r\n" +
            "a=rtpmap:34 H263/90000\r\n" +
            "a=fmtp:34 CIF=2;QCIF=2;SQCIF=2\r\n" +
            "a=acap:4 crypto:1 AES_CM_128_HMAC_SHA1_80 inline:fvjzHTEmTaVj2hgek3gzWBo99juW+5oyjOu513HK\r\n" +
            "a=acap:5 crypto:2 AES_CM_128_HMAC_SHA1_32 inline:kvGfYYxqHMedWyd/xkm5Jo6VVuG387KmEBOEW+80\r\n" +
            "a=pcfg:1 t=1 a=1,2|3\r\n" +
            "a=pcfg:2 t=2 a=1,2|3\r\n" +
            "a=pcfg:3 t=3 a=4,5\r\n" +
            "a=pcfg:4 t=4 a=4,5\r\n" +
            "a=sendrecv\r\n" +
            "a=rtcp-mux\r\n" +
            "a=ssrc:4121731982 cname:ldjWoB60jbyQlR6e\r\n" +
            "a=ssrc:4121731982 mslabel:6994f7d1-6ce9-4fbd-acfd-84e5131ca2e2\r\n" +
            "a=ssrc:4121731982 label:Doubango\r\n";


    function test_rfc5939(){
        // i_part = 1: field, 2: value
        var rfc5939_get_acap_part = function(o_hdr_a, i_part){
            var ao_match = o_hdr_a.s_value.match(/^\d\s+(\w+):([\D|\d]+)/i);
            if(ao_match && ao_match.length == 3){
                return ao_match[i_part];
            }
        }
        var rfc5939_acap_ensure = function(o_hdr_a){
            if(o_hdr_a && o_hdr_a.s_field == "acap"){
                o_hdr_a.s_field = rfc5939_get_acap_part(o_hdr_a, 1);
                o_hdr_a.s_value = rfc5939_get_acap_part(o_hdr_a, 2);
            }
        }
        var rfc5939_get_headerA_at = function(o_msg, s_media, s_field, i_index){
            var i_pos = 0;
            var get_headerA_at = function(o_sdp, s_field, i_index){
                if(o_sdp){
                    var ao_headersA = (o_sdp.ao_headers || o_sdp.ao_hdr_A);
                    for (var i = 0; i < ao_headersA.length; ++i) {
                        if(ao_headersA[i].e_type == tsdp_header_type_e.A && ao_headersA[i].s_value){
                            var b_found = (ao_headersA[i].s_field === s_field);
                            if(!b_found && ao_headersA[i].s_field == "acap"){
                                b_found = (rfc5939_get_acap_part(ao_headersA[i], 1) == s_field);
                            }
                            if(b_found && i_pos++ >= i_index){
                                return ao_headersA[i];
                            }
                        }
                    }
                }
            }

            var o_hdr_a = get_headerA_at(o_msg, s_field, i_index); // find at session level
            if(!o_hdr_a){
                return get_headerA_at(o_msg.get_header_m_by_name(s_media), s_field, i_index); // find at media level
            }
            return o_hdr_a;
        }


        var o_message = tsdp_message.prototype.Parse(__msg5);

        var o_hdr_M, o_hdr_A;
        var i_index = 0, i;

        while ((o_hdr_M = o_message.get_header_at(tsdp_header_type_e.M, i_index++))) {
            // check for "crypto:" lines (event if it's not valid to provide "crypto" lines in non-secure SDP many clients do it, so, just check)
            if (__s_browser != "firefox" && o_hdr_M.s_proto.indexOf("SAVP") < 0) {
                for (i = 0; i < o_hdr_M.ao_hdr_A.length; ++i) {
                    if (o_hdr_M.ao_hdr_A[i].s_field == "crypto") {
                        o_hdr_M.s_proto = "RTP/SAVPF";
                        break;
                    }
                }
            }

            // rfc5939: "acap:crypto"
            if (__s_browser != "firefox" && o_hdr_M.s_proto.indexOf("SAVP") < 0) {
                i = 0;
                while((o_hdr_A = rfc5939_get_headerA_at(o_message, o_hdr_M.s_media, "crypto", i++))){
                    rfc5939_acap_ensure(o_hdr_A);
                    o_hdr_M.s_proto = "RTP/SAVPF";
                    // do not break => find next "acap:crypto" lines and ensure them
                }
            }
            // rfc5939: "acap:fingerprint,setup,connection" => Mozilla Nightly
            if (__s_browser == "firefox" && o_hdr_M.s_proto.indexOf("SAVP") < 0) {
                if((o_hdr_A = rfc5939_get_headerA_at(o_message, o_hdr_M.s_media, "fingerprint", 0))){
                    rfc5939_acap_ensure(o_hdr_A);
                    if((o_hdr_A = rfc5939_get_headerA_at(o_message, o_hdr_M.s_media, "setup", 0))){
                        rfc5939_acap_ensure(o_hdr_A);
                    }
                    if((o_hdr_A = rfc5939_get_headerA_at(o_message, o_hdr_M.s_media, "connection", 0))){
                        rfc5939_acap_ensure(o_hdr_A);
                    }
                    o_hdr_M.s_proto = "UDP/TLS/RTP/SAVPF";
                }
            }
        }
        
        tsk_utils_log_info(o_message.toString());
    }

    function test_msg_parse() {
        var o_message = tsdp_message.prototype.Parse(__msg4);
        tsk_utils_log_info(o_message.toString());
    }
</script>

<!-- body -->
<body>
    <form action=''>
    <input type="button" value="Parse" onclick='test_msg_parse();' />
    <input type="button" value="rfc5939" onclick='test_rfc5939();' />
    </form>
</body>
</html>